package com.gp;

import java.util.LinkedList;
import java.util.List;

import com.gp.node.INode;
import com.gp.node.operator.IOperatorBinary;
import com.utils.CONST;
import com.utils.Random;

// generate chromes 
public class ChromeFactory {

	// create chrome with deep constrain
	public static Chrome createChrome(int treeMaxSize){
		Chrome chrome = new Chrome();
		IOperatorBinary root = (IOperatorBinary) CONST.OP_LIST[Random.nextInt(CONST.OP_LIST.length)].createNew();
		chrome.setRoot(root );
		fill(treeMaxSize,root);
		return chrome;
	}

	// create full generation
	public static List<Chrome> createGeneration(int treeMaxSize,int chromeNumber){
		List<Chrome> res = new LinkedList<Chrome>();
		for (int i = 0; i < chromeNumber; i++) {
			res.add(createChrome(treeMaxSize));
		}
		return res;
	}

	// fill the chrome with nodes (values and operators)
	private static void fill(int level,IOperatorBinary father){
		INode right = null;
		INode left = null;
		level -=1;

		if (level >0){
			if(Random.nextInt(10)> 3){                              
				right =  CONST.OP_LIST[Random.nextInt(CONST.OP_LIST.length)].createNew();
				fill(level,(IOperatorBinary) right);
			}

			if(Random.nextInt(10)> 3){                              
				left =  CONST.OP_LIST[Random.nextInt(CONST.OP_LIST.length)].createNew();
				fill(level,(IOperatorBinary) left);
			}
		}

		if(right == null){
			right = CONST.VAL_LIST[Random.nextInt(CONST.VAL_LIST.length)].createNew();    
		}

		if(left == null){
			left = CONST.VAL_LIST[Random.nextInt(CONST.VAL_LIST.length)].createNew();     
		}

		father.setRight(right);
		father.setLeft(left);
	}
}